﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bmz.Laboratory.Workflow.Repository
{
    public class EfRepository<TDataBase> : IRepository<TDataBase> where TDataBase : DbContext, new()
    {

        private readonly TDataBase _dataBase = null;

        public EfRepository()
        {
            _dataBase = new TDataBase();
        }

        public TTable Add<TTable>(TTable entity) where TTable : class
        {
            return _dataBase.Set<TTable>().Add(entity);
        }

        public IEnumerable<TTable> AddRange<TTable>(IEnumerable<TTable> listEntity) where TTable : class
        {
            return _dataBase.Set<TTable>().AddRange(listEntity);
        }

        public TTable Delete<TTable>(TTable entity) where TTable : class
        {
            _dataBase.Set<TTable>().Attach(entity);
            var table = _dataBase.Entry(entity);
            table.State = EntityState.Deleted;
            return table.Entity;
        }

        public IEnumerable<TTable> DeleteRange<TTable>(IEnumerable<TTable> listEntity) where TTable : class
        {
            var enumerable = listEntity as IList<TTable> ?? listEntity.ToList();
            foreach (var entity in enumerable)
            {
                Delete(entity);
            }
            return enumerable;
        }

        public TTable Update<TTable>(TTable entity) where TTable : class
        {
            _dataBase.Set<TTable>().Attach(entity);
            var table = _dataBase.Entry(entity);
            table.State = EntityState.Modified;
            return table.Entity;
        }

        public TTable GetEntityByKey<TTable>(int id) where TTable : class
        {
            return _dataBase.Set<TTable>().Find(id);
        }

        public IQueryable<TTable> GetEntityList<TTable>(Func<TTable, bool> filter) where TTable : class
        {
            return _dataBase.Set<TTable>().Where(filter).AsQueryable();
        }

        public int ExecuteSqlCommand(string sql, params object[] parameters)
        {
            parameters = parameters ?? new object[0];
            return _dataBase.Database.ExecuteSqlCommand(sql, parameters);
        }

        public IList<TTable> SqlQuery<TTable>(string sql, params object[] parameters)
        {
            return _dataBase.Database.SqlQuery<TTable>(sql, parameters).ToList();
        }

        public int Commit(bool isDsipose = true)
        {
            return _dataBase.SaveChanges();
        }

        public TDataBase DbContext
        {
            get { return _dataBase; }

        }

        public void Dispose()
        {
            _dataBase.Dispose();
        }
    }
}
